package com.heima.search.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.search.dtos.UserSearchDto;
import com.heima.search.service.ArticleSearchService;
import com.heima.search.service.HistoryService;
import com.heima.utils.thread.ApUserThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author jack
 * @data 2023 8:36
 */
@Service
@Slf4j
public class ArticleSearchServiceImpl implements ArticleSearchService {
    @Autowired
    private RestHighLevelClient restHighLevelClient;
    @Autowired
    private HistoryService historyService;
    /**
     * app文章搜索
     *
     * @param searchDto
     * @return
     */
    @Override
    public ResponseResult search(UserSearchDto searchDto) {
        try {

            //维护当前用户的搜索历史记录
            Integer user = ApUserThreadLocalUtil.getUser();
            if (user != null && user != 0){
                historyService.saveOrUpdate(searchDto.getSearchWords());
            }


            //1. 准备一个searchRequest
            SearchRequest request = new SearchRequest("app_info_article");

            //2. 准备查询条件：source
            //2.1 query查询条件部分
            BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
            boolQuery.must(QueryBuilders.multiMatchQuery(searchDto.getSearchWords(),"title","content"));
            boolQuery.filter(QueryBuilders.rangeQuery("publishTime").lte(searchDto.getMinBehotTime()));
            request.source().query(boolQuery);
            //2.2 form,size分页属性
            request.source().from(searchDto.getFromIndex());
            request.source().size(searchDto.getPageSize());

            //2.3 sort排序字段
            request.source().sort("publishTime", SortOrder.DESC);

            //2.4 highlight高亮字段设置
            request.source().highlighter(new HighlightBuilder().field("title")
                    .preTags("<font style='color: red; font-size: inherit;'>")
                    .postTags("</font>"));

            //3. 发送查询请求，并接收响应
            SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);

            //4. 解析响应结果，封装数据返回给前端
            SearchHit[] hits = response.getHits().getHits();

            List<JSONObject> list = new ArrayList<>();

            for (SearchHit hit : hits) {
                String articleJSON = hit.getSourceAsString();
                JSONObject articleJsonObject = JSONObject.parseObject(articleJSON);
                articleJsonObject.put("h_title",articleJsonObject.get("title"));

                Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                if (highlightFields != null && highlightFields.size() > 0){
                    String highTitle = highlightFields.get("title").getFragments()[0].toString();
                    articleJsonObject.put("h_title",highTitle);
                }

                list.add(articleJsonObject);
            }

            //返回结果
            return  ResponseResult.okResult(list);

        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     * app文章数据同步
     *
     * @param articleJSON
     */
    @Override
    public void saveArticle(String articleJSON) {
        JSONObject articleJSONObject = JSONObject.parseObject(articleJSON);

        try {
            //构建一个IndexRequest
            IndexRequest request = new IndexRequest("app_info_article").id(articleJSONObject.getString("id"));
            request.source(articleJSON, XContentType.JSON);
            restHighLevelClient.index(request, RequestOptions.DEFAULT);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
